package com.art.base.util;

import android.annotation.SuppressLint;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.text.TextUtils;

import com.art.base.util.log.LogUtil;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

/**
 * @author dongtianhao
 * @ClassName: ApkUtils
 * @Description: TODO(这里用一句话描述这个类的作用)
 * @date 2016年8月4日 下午5:01:38
 */
public class ApkUtils {

    /**
     * 安装一个apk文件
     */
    public static void install(Context context, File uriFile) {
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setDataAndType(Uri.fromFile(uriFile), "application/vnd.android.package-archive");
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent);
        // ToastShow.shortMessage("install");
    }

    /**
     * 静默安装. 失败则用普通安装
     * <p>
     * 中科创达设备才能用静默.
     */
    public static void installSilent(Context context, File uriFile) {
        // Uri uri = Uri.parse("file://" + uriFile.getPath() + "/" +
        // uriFile.getName());
        try {
            Uri uri = Uri.fromFile(uriFile);
            ToastShow.shortMessage("开始安装: " + uriFile.getName());
            Intent installintent = new Intent("android.intent.action.SECURE_INSTALL_PACKAGE");
            installintent.addCategory(Intent.CATEGORY_DEFAULT);
            installintent.setData(uri);
            installintent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(installintent);
        } catch (Exception e) {
            e.printStackTrace();
            install(context, uriFile);
        }
    }

    /**
     * 卸载一个app
     */
    public static void uninstall(Context context, String packageName) {
        // 通过程序的包名创建URI
        Uri packageURI = Uri.parse("package:" + packageName);
        // 创建Intent意图
        Intent intent = new Intent(Intent.ACTION_DELETE, packageURI);
        // 执行卸载程序
        context.startActivity(intent);
        // ToastShow.shortMessage("uninstall");
    }

    /**
     * 静默卸载 仅限特定设备使用
     *
     * @param context
     * @param packageName
     */
    public static void uninstallSilent(Context context, String packageName) {
        try {
            // ToastShow.shortMessage("uninstallSilent");
            Uri uri = Uri.parse("package:" + packageName);
            Intent installintent = new Intent("android.intent.action.SECURE_UNINSTALL_PACKAGE");
            installintent.addCategory(Intent.CATEGORY_DEFAULT);
            installintent.setData(uri);
            installintent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(installintent);
        } catch (Exception e) {
            e.printStackTrace();
            uninstall(context, packageName);
        }
    }

    /**
     * 根据包名获取安装的应用的版本号
     *
     * @param context
     * @param pkg
     * @return
     */
    public static int getVersionCode(Context context, String pkg) {
        try {
            return context.getPackageManager().getPackageInfo(pkg, 0).versionCode;
        } catch (NameNotFoundException e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 判断手机是否已经安装了,指定包名和版本号的应用
     *
     * @return
     */
    public static boolean isInstalled(Context context, String pkg, int versionCode) {
        try {
            PackageInfo packageInfo = context.getApplicationContext().getPackageManager().getPackageInfo(pkg, 0);
            LogUtil.trace(6,"",packageInfo.versionCode + "code" + versionCode);
            if (isAvailable(context, pkg) && packageInfo.versionCode == versionCode) {
                return true;
            }
        } catch (NameNotFoundException e) {
            e.printStackTrace();
            return false;
        }
        return false;
    }

    /**
     * 判断手机是否需要更新
     *
     * @return
     */
    public static boolean isNeedUpdate(Context context, String pkg, int versionCode) {
        try {
            PackageInfo packageInfo = context.getApplicationContext().getPackageManager().getPackageInfo(pkg, 0);
            LogUtil.trace(6,"",packageInfo.versionCode + "code" + versionCode);
            if (packageInfo != null) {
                if (isAvailable(context, pkg) && packageInfo.versionCode < versionCode) {
                    return true;
                }
            }
        } catch (NameNotFoundException e) {
            e.printStackTrace();
            return false;
        }
        return false;
    }

    /**
     * 判断手机是否安装应用并且不需要升级
     * @return
     */
    public static boolean isNeedOpen(Context context, String pkg, int versionCode) {
        // 获取packagemanager
        final PackageManager packageManager = context.getApplicationContext().getPackageManager();
        // 获取所有已安装程序的包信息
        List<PackageInfo> packageInfos = packageManager.getInstalledPackages(0);
        // 从pinfo中将包名字逐一取出
        if (packageInfos != null) {
            for (int i = 0; i < packageInfos.size(); i++) {
                if (pkg.equals(packageInfos.get(i).packageName) && packageInfos.get(i).versionCode >= versionCode) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 检查手机上是否安装了指定包名的软件
     */
    public static boolean isAvailable(Context context, String packageName) {
        LogUtil.trace(6,"packageName",packageName);
        // 获取packagemanager
        final PackageManager packageManager = context.getApplicationContext().getPackageManager();
        // 获取所有已安装程序的包信息
        List<PackageInfo> packageInfos = packageManager.getInstalledPackages(0);
        // 用于存储所有已安装程序的包名
        List<String> packageNames = new ArrayList<>();
        // 从pinfo中将包名字逐一取出，压入pName list中
        if (packageInfos != null) {
            for (int i = 0; i < packageInfos.size(); i++) {
                String packName = packageInfos.get(i).packageName;
                packageNames.add(packName);
            }
        }
        // 判断packageNames中是否有目标程序的包名，有TRUE，没有FALSE
        return packageNames.contains(packageName);
    }
    //
    // /** 检查手机上是否安装了指定的软件 */
    // public static boolean isAvailable(Context context, File file) {
    // return isAvailable(context,
    // getPackageName(context, file.getAbsolutePath()));
    // }

    /**
     * 根据文件路径获取包名
     */
    public static String getPackageName(Context context, String filePath) {
        PackageManager packageManager = context.getApplicationContext().getPackageManager();
        PackageInfo info = packageManager.getPackageArchiveInfo(filePath, PackageManager.GET_ACTIVITIES);
        if (info != null) {
            ApplicationInfo appInfo = info.applicationInfo;
            return appInfo.packageName; // 得到安装包名称
        }
        return null;
    }

    /**
     * 从apk中获取版本信息
     */
    @SuppressLint("NewApi")
    public static String getChannelFromApk(Context context, String channelPrefix) {
        // 从apk包中获取
        ApplicationInfo appinfo = context.getApplicationContext().getApplicationInfo();
        String sourceDir = appinfo.sourceDir;
        // 默认放在meta-inf/里， 所以需要再拼接一下
        String key = "META-INF/" + channelPrefix;
        String ret = "";
        ZipFile zipfile = null;
        try {
            zipfile = new ZipFile(sourceDir);
            Enumeration<?> entries = zipfile.entries();
            while (entries.hasMoreElements()) {
                ZipEntry entry = ((ZipEntry) entries.nextElement());
                String entryName = entry.getName();
                if (entryName.startsWith(key)) {
                    ret = entryName;
                    break;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (zipfile != null) {
                try {
                    zipfile.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        String[] split = ret.split(channelPrefix);
        String channel = "";
        if (split.length >= 2) {
            channel = ret.substring(key.length());
        }
        return channel;
    }

    /**
     * 打开指定包名的app
     *
     * @param context
     * @param packageName
     */
    @SuppressLint("NewApi")
    public static void openAPP(Context context, String packageName) {
        // PackageManager manager = context.getPackageManager();
        // Intent app = manager.getLaunchIntentForPackage(packageName);
        // context.startActivity(app);
        openPackage(context.getApplicationContext(), packageName);
    }
    /**
     * 打开指定包名的app 有图标
     *
     * @param context
     * @param packageName
     */
    @SuppressLint("NewApi")
    public static void openAPP(Context context, String packageName, String activity) {
        openPackage(context.getApplicationContext(), packageName, activity);
    }

    private static Intent getAppOpenIntentByPackageName(Context context, String packageName) {
        // MainActivity完整名
        String mainAct = null;
        // 根据包名寻找MainActivity
        PackageManager pkgMag = context.getApplicationContext().getPackageManager();
        Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.addCategory(Intent.CATEGORY_LAUNCHER);
        intent.setFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | Intent.FLAG_ACTIVITY_NEW_TASK);

        List<ResolveInfo> list = pkgMag.queryIntentActivities(intent, PackageManager.GET_ACTIVITIES);
        for (int i = 0; i < list.size(); i++) {
            ResolveInfo info = list.get(i);
            if (info.activityInfo.packageName.equals(packageName)) {
                mainAct = info.activityInfo.name;
                break;
            }
        }
        if (TextUtils.isEmpty(mainAct)) {
            return null;
        }
        intent.setComponent(new ComponentName(packageName, mainAct));
        return intent;
    }

    private static Context getPackageContext(Context context, String packageName) {
        Context pkgContext = null;
        if (context.getApplicationContext().getPackageName().equals(packageName)) {
            pkgContext = context.getApplicationContext();
        } else {
            // 创建第三方应用的上下文环境
            try {
                pkgContext = context.createPackageContext(packageName,
                        Context.CONTEXT_IGNORE_SECURITY | Context.CONTEXT_INCLUDE_CODE);
            } catch (NameNotFoundException e) {
                e.printStackTrace();
            }
        }
        return pkgContext;
    }

    /**
     * 打开app
     *
     * @param context
     * @param packageName
     * @return
     */
    public static boolean openPackage(Context context, String packageName) {
        Context pkgContext = getPackageContext(context.getApplicationContext(), packageName);
        Intent intent = getAppOpenIntentByPackageName(context, packageName);
        if (pkgContext != null && intent != null) {
            pkgContext.startActivity(intent);
            return true;
        }
        return false;
    }
    /**
     * 打开app
     *
     * @param context
     * @param packageName
     * @param activity
     *            三方app对应的启动activity路径
     * @return
     */
    public static boolean openPackage(Context context, String packageName, String activity) {
        Context pkgContext = getPackageContext(context.getApplicationContext(), packageName);
        Intent intent = new Intent();
        // a应用启动b应用
        ComponentName cn = new ComponentName(packageName, activity);
        intent.setComponent(cn);
        Uri uri = Uri.parse(packageName);// 此处应与B程序中Data中标签一致
        intent.setData(uri);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        if (pkgContext != null && intent != null) {
            pkgContext.startActivity(intent);
            return true;
        }
        return false;
    }

    /**
     * 根据包名获取程序 图标
     *
     * @param context
     * @param pkgName
     * @return
     */
    public static Drawable getAppIcon(Context context, String pkgName) {
        try {
            ApplicationInfo info = context.getApplicationContext().getPackageManager().getApplicationInfo(pkgName, 0);
            return info.loadIcon(context.getPackageManager());
        } catch (NameNotFoundException e) {
            e.printStackTrace();

        }
        return null;
    }

    /**
     * 获取版本名称 versionName例如1.0
     *
     * @return
     */
    public static String getVersionName(Context c) {
        String versionName = "";
        try {
            PackageManager pm = c.getPackageManager();
            PackageInfo pi = pm.getPackageInfo(c.getPackageName(), 0);
            versionName = pi.versionName;
        } catch (NameNotFoundException e) {
            e.printStackTrace();
        }
        return versionName;
    }

    /**
     * 获取版本编号 versionCode 例如1
     *
     * @return
     */
    public static int getVersionCode(Context c) {
        int versionCode = 0;
        try {
            PackageManager pm = c.getPackageManager();
            PackageInfo pi = pm.getPackageInfo(c.getPackageName(), 0);
            versionCode = pi.versionCode;
        } catch (NameNotFoundException e) {
            e.printStackTrace();
        }
        return versionCode;
    }

}
